package com.yuhuihui.common.utils;

import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 内存缓存
 *
 * @author yuhh
 * @date 2023-05-25 14:13:19
 */
public class GuavaCacheUtils {

	private static final Logger logger = LoggerFactory.getLogger(GuavaCacheUtils.class);
	
	/**
	 * 缓存组
	 */
	private static final Map<String, Cache<String, Object>> MAP = new HashMap<>();
	
	/**
	 * 默认使用的缓存组
	 */
	private static final String DEFAULT_CACHE_GROUP = "GuavaCacheUtils-DEFAULT_CACHE_GROUP";


	/**
	 * 创建默认缓存
	 *
	 * @param maxSize 最大数量
	 * @param timeOut 过期时间 单位秒
	 * @return {@link Cache }<{@link String }, {@link Object }> 缓存组
	 * @author yuhh
	 * @date 2023-05-25 14:13:28
	 */
	public static Cache<String, Object> buildCache(Long maxSize,Long timeOut){
		if (maxSize == null || maxSize < 1) {
			//默认大小1000
			maxSize = 1000L;
		}
		if (timeOut == null || timeOut < 1) {
			//默认3小时
			timeOut = 3600 * 3L;
		}
		
		return CacheBuilder.newBuilder().maximumSize(maxSize).expireAfterWrite(timeOut, TimeUnit.SECONDS).build();
	}

	/**
	 * 注册缓存组
	 *
	 * @param cacheGroup 缓存组名
	 * @param cache      缓存
	 * @author yuhh
	 * @date 2023-05-25 14:13:34
	 */
	public static synchronized void registryCache(String cacheGroup,Cache<String, Object> cache) {
		//不可重复注册
		MAP.putIfAbsent(cacheGroup, cache);
	}

	/**
	 * 删除缓存组
	 *
	 * @param cacheGroup 缓存组名
	 * @author yuhh
	 * @date 2023-05-25 14:13:37
	 */
	public static synchronized void clearCache(String cacheGroup){
		MAP.remove(cacheGroup);
	}

	/**
	 * 删除所有缓存组
	 *
	 * @author yuhh
	 * @date 2023-05-25 14:13:40
	 */
	public static synchronized void clearAllCache(){
		MAP.clear();
	}

	/**
	 * 读取缓存
	 *
	 * @param cacheGroup 缓存组名
	 * @return {@link Cache }<{@link String }, {@link Object }> 缓存数据
	 * @author yuhh
	 * @date 2023-05-25 14:13:44
	 */
	private static Cache<String, Object> getCache(String cacheGroup) {
		Cache<String, Object> cache = MAP.get(cacheGroup);
		//如果缓存为空 自动注册默认
		if (cache==null) {
			cache=buildCache(null, null);
			logger.info("缓存自动注册  :{}",cacheGroup);
			registryCache(cacheGroup, cache);
		}
		return cache;
	}

	/**
	 * 读缓存值
	 *
	 * @param cacheGroup 缓存组名
	 * @param cacheName  缓存名
	 * @return {@link T } 缓存数据
	 * @author yuhh
	 * @date 2023-05-25 14:13:58
	 */
	@SuppressWarnings("unchecked")
	public static <T> T getCacheVal(String cacheGroup,String cacheName) {
		return (T) getCache(cacheGroup).asMap().get(cacheName);
	}

	/**
	 * 写入缓存
	 *
	 * @param cacheGroup 缓存组名
	 * @param cacheName  缓存名
	 * @param val        缓存值
	 * @author yuhh
	 * @date 2023-05-25 14:14:04
	 */
	public static void setCacheVal(String cacheGroup,String cacheName,Object val) {
		getCache(cacheGroup).put(cacheName, val);
	}

	/**
	 * 删除缓存
	 *
	 * @param cacheGroup 缓存组名
	 * @param cacheName  缓存名
	 * @author yuhh
	 * @date 2023-05-25 14:14:07
	 */
	public static void clearCache(String cacheGroup,String cacheName) {
		getCache(cacheGroup).asMap().remove(cacheName);
	}

	/**
	 * 根据cacheName从默认的缓存组里删除
	 *
	 * @param cacheName 缓存名
	 * @author yuhh
	 * @date 2023-05-25 14:14:09
	 */
	public static void clearDefaultCache(String cacheName) {
		clearCache(DEFAULT_CACHE_GROUP, cacheName);
	}

	/**
	 * 向默认的缓存组里注册缓存
	 *
	 * @param cacheName 缓存名
	 * @param val       缓存值
	 * @author yuhh
	 * @date 2023-05-25 14:14:20
	 */

	public static void setDefaultCacheVal(String cacheName,Object val) {
		setCacheVal(DEFAULT_CACHE_GROUP, cacheName, val);
	}

	/**
	 * 根据cacheName从默认的缓存组里得到value
	 *
	 * @param cacheName 缓存名
	 * @return {@link T } 缓存值
	 * @author yuhh
	 * @date 2023-05-25 14:18:45
	 */
	public static <T> T getDefaultCacheVal(String cacheName) {
		return getCacheVal(DEFAULT_CACHE_GROUP, cacheName);
	}

	private GuavaCacheUtils(){}
}
